﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;
using Microsoft.SharePoint;

namespace FieldCopier
{
    public partial class frmMain : Form
    {
        public List<SPField> DifferenceQuery;
        public SPList DesintationList;

        public frmMain()
        {
            InitializeComponent();
        }

        private void BtnGetDifferencesClick(object sender, EventArgs e)
        {
            lbDifferences.Enabled = true;
            btnCopy.Enabled = true;
            lbDifferences.Items.Clear();

            List<SPField> sourceFieldCollection = new List<SPField>();
            List<SPField> destinationFieldCollection = new List<SPField>();
            PopulateTypedFieldCollections(destinationFieldCollection, sourceFieldCollection);

            DifferenceQuery = new List<SPField>();

            foreach (SPField sourceField in sourceFieldCollection)
            {
                bool exists = false;
                string sourceTitle = sourceField.Title;
                foreach (string destTitle in destinationFieldCollection.
                    Select(destField => destField.Title).
                    Where(destTitle => sourceTitle == destTitle))
                {
                    exists = true;
                }
                if (!exists)
                {
                    DifferenceQuery.Add(sourceField);
                }
            }
            
            foreach (SPField field in DifferenceQuery)
            {
                lbDifferences.Items.Add(field.Title);
            }

        }

        private void PopulateTypedFieldCollections(List<SPField> destinationFieldCollection, List<SPField> sourceFieldCollection)
        {
            using (SPSite site = new SPSite(tbUrl.Text))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPList sourceList = web.Lists[ddlSourceList.SelectedItem.ToString()];
                    DesintationList = web.Lists[ddlDesintationList.SelectedItem.ToString()];

                    sourceFieldCollection.AddRange(
                        sourceList.Fields.Cast<SPField>().Where(field => !field.ReadOnlyField && !field.Hidden));
                    destinationFieldCollection.AddRange(
                        DesintationList.Fields.Cast<SPField>().Where(
                            desintationField => !desintationField.ReadOnlyField && !desintationField.Hidden));
                }
            }
        }

        private void BtnGetListsClick(object sender, EventArgs e)
        {
            using (SPSite site = new SPSite(tbUrl.Text))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPListCollection listCollection = web.Lists;

                    ddlDesintationList.Enabled = true;
                    ddlSourceList.Enabled = true;

                    ddlDesintationList.Items.Clear();
                    ddlSourceList.Items.Clear();

                    foreach (SPList list in listCollection)
                    {
                        ddlDesintationList.Items.Add(list.Title);
                        ddlSourceList.Items.Add(list.Title);
                    }
                }
            }
            btnGetDifferences.Enabled = true;
        }

        private void BtnCopyClick(object sender, EventArgs e)
        {
            foreach (SPField field in DifferenceQuery)
            {
                if (DesintationList.Fields.ContainsField(field.Title)) continue;
                var fieldXdoc = XDocument.Parse(field.SchemaXml);
                var fieldElement = fieldXdoc.Element("Field");
                if (fieldElement == null) continue;
                XAttribute displayName = fieldElement.Attribute("DisplayName");
                XAttribute id = fieldElement.Attribute("ID");
                if (displayName == null || id == null) continue;
                displayName.Value = field.Title;
                Guid titleGuidConstant = new Guid("fa564e0f-0c70-4ab9-b863-0177e6ddd247");
                Guid curIteratedFieldId = new Guid(id.Value);
                if (titleGuidConstant == curIteratedFieldId) continue;
                DesintationList.Fields.AddFieldAsXml(fieldXdoc.ToString());
                SPField newfield = DesintationList.Fields.GetField(displayName.Value);
                newfield.Update();
            }
            Close();
        }

        private void BtnCancelClick(object sender, EventArgs e)
        {
            Close();
        }
    }
}
